home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / src / WBBump_src.lha / WBBump_src / chunkyimage.e < prev    next >
Encoding:
Text File  |  1999-06-30  |  7.4 KB  |  405 lines

  1. /* ************* */
  2. /* chunkyimage.e */
  3. /* ************* */
  4.  
  5.  
  6.  
  7. /*
  8.     WBBump - Bumpmapping on the Workbench!
  9.  
  10.     Copyright (C) 1999  Thomas Jensen - dm98411@edb.tietgen.dk
  11.  
  12.     This program is free software; you can redistribute it and/or modify
  13.     it under the terms of the GNU General Public License as published by
  14.     the Free Software Foundation; either version 2 of the License, or
  15.     (at your option) any later version.
  16.  
  17.     This program is distributed in the hope that it will be useful,
  18.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.     GNU General Public License for more details.
  21.  
  22.     You should have received a copy of the GNU General Public License
  23.     along with this program; if not, write to the Free Software Foundation,
  24.     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25. */
  26.  
  27.  
  28.  
  29. /*
  30.     NOTE:
  31.         cgx library must be open!
  32.  
  33.         utility.library must be open
  34.  
  35.         datatypes.library must be open
  36. */
  37.  
  38.  
  39. OPT MODULE
  40.  
  41.  
  42.  
  43.  
  44. MODULE    'intuition/intuition',
  45.         'intuition/screens',
  46.         'intuition/gadgetclass',
  47.  
  48.         'exec/memory',
  49.  
  50.         'graphics/gfx',
  51.         'graphics/rastport',
  52.         'graphics/view',
  53.  
  54.         'utility',
  55.         'utility/tagitem',
  56.  
  57.         'cybergraphics',
  58.         'cybergraphx/cybergraphics',
  59.  
  60.         'datatypes',
  61.         'datatypes/datatypes',
  62.         'datatypes/datatypesclass',
  63.         'datatypes/pictureclass',
  64.  
  65.         'amigalib/boopsi',
  66.  
  67.         'dos/dos'
  68.  
  69.  
  70. MODULE    '*errors',
  71.         '*threads',
  72.         '*chunkytools'
  73.  
  74.  
  75.  
  76. EXPORT CONST    CIMGTYP_8BIT    = RECTFMT_LUT8,
  77.                 CIMGTYP_RGB        = RECTFMT_RGB
  78.  
  79.  
  80.  
  81. EXPORT ENUM    CIMGTAG_LOCK_BUF=TAG_USER
  82.  
  83. EXPORT ENUM    CIMG_WRITE_ASYNC=TAG_USER,
  84.             CIMG_WRITE_LPB
  85.  
  86.  
  87. ENUM    CIMG_TCMD_WRITEFULL = TCMD_USER
  88.  
  89.  
  90. EXPORT OBJECT cimg
  91. PRIVATE
  92.     buffer    :    PTR TO CHAR
  93.  
  94.     /* next two are only used if async calls are made */
  95.     thread    :    PTR TO thread
  96.     job        :    PTR TO job
  97.  
  98.     temprp    :    PTR TO rastport
  99.     
  100. PUBLIC
  101.     type    :    LONG
  102.     width    :    LONG    -> in pixels
  103.     height    :    LONG    -> in pixels
  104.     bpp        :    INT        -> bytes per pixel
  105. ENDOBJECT
  106.  
  107.  
  108.  
  109. /* allocate a new chunky image */
  110. PROC alloc(width, height, type, tags=NIL:PTR TO tagitem) OF cimg HANDLE
  111.  
  112.     self.thread := NIL
  113.     self.job := NIL
  114.  
  115.  
  116.     SELECT type
  117.     CASE CIMGTYP_8BIT
  118.         self.bpp := 1
  119.     CASE CIMGTYP_RGB
  120.         self.bpp := 3
  121.     DEFAULT
  122.         eThrow(ERR_INTERNAL, 'Unsupported chunky format in .alloc() (type was %ld)', [type])
  123.     ENDSELECT
  124.  
  125.     self.type := type
  126.     self.width := width
  127.     self.height := height
  128.     self.buffer := NewR(self.bpp * self.width * self.height)
  129. EXCEPT DO
  130.     ReThrow()
  131. ENDPROC
  132.  
  133.  
  134.  
  135.  
  136. PROC createthread() OF cimg HANDLE
  137.     IF self.thread = NIL
  138.         NEW self.thread.create({cimg_thread}, 'blit thread', [
  139.             TTAG_CREATE_APENDNAME, TRUE,
  140.             TTAG_CREATE_RELATIVEPRI, 1,
  141.             NIL])
  142.     ENDIF
  143. EXCEPT DO
  144.     ReThrow()
  145. ENDPROC
  146.  
  147.  
  148.  
  149. PROC read_full(rp:PTR TO rastport, x, y) OF cimg HANDLE
  150.     DEF    type,
  151.         temprp=NIL
  152.  
  153.  
  154.     type := self.type
  155.     SELECT type
  156.     CASE CIMGTYP_8BIT
  157.  
  158.         temprp := alloc_temprp(rp, self.width)
  159.  
  160.         rastport2chunky(rp, self.buffer, x, y, self.width, self.height, temprp)
  161.  
  162.     CASE CIMGTYP_RGB
  163.         ReadPixelArray(self.buffer, 0, 0, self.bpp * self.width, rp, x, y, self.width, self.height,    RECTFMT_RGB)
  164.  
  165.     DEFAULT
  166.         eThrow(ERR_INTERNAL, 'Unsuported cimg.type (%ld)', [type])
  167.  
  168.     ENDSELECT
  169.             
  170.  
  171. EXCEPT DO
  172.     IF temprp THEN free_temprp(temprp)
  173.     ReThrow()
  174. ENDPROC
  175.  
  176.  
  177. PROC write_full(rp, x, y, tags=NIL:PTR TO tagitem) OF cimg HANDLE
  178.     DEF    async=FALSE,
  179.         lines_per_blit=0,
  180.         type,
  181.         iy,
  182.         the_rest,
  183.         temprp=NIL
  184.  
  185.     IF tags
  186.         async := GetTagData(CIMG_WRITE_ASYNC, FALSE, tags)
  187.         lines_per_blit := GetTagData(CIMG_WRITE_LPB, 0, tags)
  188.     ENDIF
  189.  
  190. /* testing */
  191. async := FALSE
  192.  
  193.     IF async
  194.  
  195.         IF self.thread = NIL THEN self.createthread()
  196.  
  197.         IF self.job THEN self.thread.waitjob(self.job)
  198.  
  199.         self.job := self.thread.sendjob(CIMG_TCMD_WRITEFULL, [self, rp, x, y, lines_per_blit])
  200.  
  201.     ELSE
  202.  
  203.         type := self.type
  204.  
  205.         SELECT type
  206.         CASE CIMGTYP_8BIT
  207.  
  208.             temprp := alloc_temprp(rp, self.width)
  209.  
  210.             chunky2rastport(rp, self.buffer, 0, 0, self.width, self.height, temprp)
  211.  
  212.         CASE CIMGTYP_RGB
  213.  
  214.             IF lines_per_blit < 1
  215.                 WritePixelArray(self.buffer, 0, 0, self.width * self.bpp, rp, x, y, self.width, self.height, self.type)
  216.             ELSE
  217.                 the_rest := Mod(self.height, lines_per_blit)
  218.                 FOR iy := 0 TO (self.height / lines_per_blit)-1
  219.                     WritePixelArray(self.buffer, 0, iy * lines_per_blit, self.width * self.bpp, rp, x, y + (iy * lines_per_blit), self.width, lines_per_blit, self.type)
  220.                 ENDFOR
  221.                 WritePixelArray(self.buffer, 0, self.height - the_rest - 1, self.width * self.bpp, rp, x, y + self.height - the_rest - 1, self.width, the_rest, self.type)
  222.             ENDIF
  223.  
  224.         DEFAULT
  225.             eThrow(ERR_INTERNAL, 'Unsupported chunky format in .write_full() (type was %ld)', [type])
  226.         ENDSELECT
  227.  
  228.     ENDIF
  229.  
  230. EXCEPT DO
  231.     IF temprp THEN free_temprp(temprp)
  232.     ReThrow()
  233. ENDPROC
  234.  
  235.  
  236.  
  237.  
  238.  
  239. PROC newfromDT(filename) OF cimg HANDLE
  240.     DEF    dto=NIL,                        -> datatype object
  241.         bm=NIL:PTR TO bitmap,            -> bitmap of datatype object
  242.         bmh=NIL:PTR TO bitmapheader,    -> bitmapheader of datatype object
  243.         gpl=NIL:PTR TO gplayout,
  244.         ncol,                            -> number of colors in dt picture
  245.         buf=NIL,
  246.         width, height
  247.  
  248.  
  249.  
  250.     self.thread := NIL
  251.     self.job := NIL
  252.  
  253.  
  254.     /* load the freak'n picture */
  255.  
  256.     dto := NewDTObjectA(filename, [
  257.  
  258.         DTA_GROUPID, GID_PICTURE,
  259.  
  260.         PDTA_REMAP, FALSE,
  261.  
  262.         NIL])
  263.  
  264.     IF dto = NIL THEN eThrow(ERR_DT, 'Unable to load file: "%s"', [filename])
  265.  
  266.  
  267.     /* perform gplayout method (else we wont get a bitmap) */
  268.  
  269.     NEW gpl
  270.     gpl.methodid := DTM_PROCLAYOUT
  271.     gpl.ginfo := NIL
  272.     gpl.initial := 1
  273.  
  274.     IF doMethodA(dto, gpl) = 0 THEN Throw(ERR_DT, 'Error during ProcLayout method')
  275.  
  276.  
  277.  
  278.     /* get attrs */
  279.  
  280.     GetDTAttrsA(dto, [
  281.         PDTA_BITMAPHEADER,    {bmh},
  282.         PDTA_BITMAP,        {bm},
  283.         PDTA_NUMCOLORS,        {ncol},
  284.         DTA_NOMINALHORIZ,    {width},
  285.         DTA_NOMINALVERT,    {height},
  286.         NIL])
  287.  
  288.  
  289.     /* alloc a buffer of needed dimensions */
  290.  
  291.     self.alloc(bmh.width, bmh.height, CIMGTYP_8BIT)
  292.  
  293.  
  294.     /* get direct access */
  295.  
  296.     IF self.lock([CIMGTAG_LOCK_BUF, {buf}, NIL]) = FALSE THEN Raise(ERR_LOCKCIMG)
  297.  
  298.  
  299.     /* convert to chunky */
  300.  
  301.     bitmap2chunky(bm, buf, 0, 0, self.width, self.height)
  302.  
  303.  
  304. EXCEPT DO
  305.     IF dto THEN DisposeDTObject(dto)
  306.     IF buf THEN self.unlock()
  307.     ReThrow()
  308. ENDPROC
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320. PROC lock(tags:PTR TO tagitem) OF cimg
  321.     DEF    buf:PTR TO LONG
  322.  
  323.     buf := GetTagData(CIMGTAG_LOCK_BUF, 0, tags)
  324.  
  325.     IF buf THEN buf[0] := self.buffer
  326. ENDPROC TRUE
  327.  
  328.  
  329. PROC unlock() OF cimg IS NIL
  330.  
  331.  
  332.  
  333.  
  334.  
  335. PROC end() OF cimg
  336.     END self.thread
  337.     IF self.buffer THEN Dispose(self.buffer)
  338. ENDPROC
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349. /* thread code */
  350.  
  351.  
  352. PROC cimg_thread(thread:PTR TO thread, job:PTR TO job)
  353.     DEF    cmd,
  354.         iy,
  355.         type,
  356.         lines_per_blit,
  357.         the_rest,
  358.         temprp=NIL,
  359.         cimg:PTR TO cimg,
  360.         rp,
  361.         x, y
  362.  
  363.     cimg := job.input[0]
  364.     rp := job.input[1]
  365.     x := job.input[2]
  366.     y := job.input[3]
  367.     lines_per_blit := job.input[4]
  368.  
  369.     cmd := job.command
  370.  
  371.     SELECT cmd
  372.     CASE CIMG_TCMD_WRITEFULL
  373.         type := cimg.type
  374.  
  375.         SELECT type
  376.         CASE CIMGTYP_8BIT
  377.  
  378.             temprp := alloc_temprp(rp, cimg.width)
  379.  
  380.             chunky2rastport(rp, cimg.buffer, 0, 0, cimg.width, cimg.height, temprp)
  381.  
  382.         CASE CIMGTYP_RGB
  383.  
  384.             IF lines_per_blit < 1
  385.                 WritePixelArray(cimg.buffer, 0, 0,  cimg.width * cimg.bpp, rp, x, y, cimg.width, cimg.height, cimg.type)
  386.             ELSE
  387.                 the_rest := Mod(cimg.height, lines_per_blit)
  388.                 FOR iy := 0 TO (cimg.height / lines_per_blit)-1
  389.                     WritePixelArray(cimg.buffer, 0, iy * lines_per_blit,  cimg.width * cimg.bpp, rp, x, y + (iy * lines_per_blit), cimg.width, lines_per_blit, cimg.type)
  390.                 ENDFOR
  391.                 WritePixelArray(cimg.buffer, 0, cimg.height - the_rest - 1, cimg.width * cimg.bpp, rp, x, y + cimg.height - the_rest - 1, cimg.width, the_rest, cimg.type)
  392.             ENDIF
  393.  
  394.         DEFAULT
  395.             eThrow(ERR_INTERNAL, 'Unsupported chunky format in .write_full() (type was %ld)', [type])
  396.         ENDSELECT
  397.  
  398.     ENDSELECT
  399.  
  400.     free_temprp(temprp)
  401.  
  402. ENDPROC TRUE
  403.  
  404.  
  405.